#!/bin/sh

# src/tools/make_ctags [-e] [-n]
# If -e is specified, generate tags files for emacs.
# If -n is specified, don't create symbolic links of tags file.
usage="Usage:  $0 [-e][-n]"
if [ $# -gt 2 ]
then	echo $usage
	exit 1
fi

EMACS_MODE=
NO_SYMLINK=
IS_EXUBERANT=
PROG="ctags"
TAGS_OPT="-a -f"
TAGS_FILE="tags"
FLAGS=
IGNORE_IDENTIFIES=

while [ $# -gt 0 ]
do
	if [ $1 = "-e" ]
	then	EMACS_MODE="Y"
	elif [ $1 = "-n" ]
	then	NO_SYMLINK="Y"
	else
		echo $usage
		exit 1
	fi
	shift
done

if [ ! "$EMACS_MODE" ]
then	(command -v ctags >/dev/null) || \
	{ echo "'ctags' program not found" 1>&2; exit 1; }
fi

ctags --version 2>&1 | grep Exuberant && IS_EXUBERANT="Y"

if [ "$EMACS_MODE" ]
then	TAGS_FILE="TAGS"
	if [ "$IS_EXUBERANT" ]
	then PROG="ctags -e"
	else	(command -v etags >/dev/null) || \
		{ echo "neither 'etags' nor exuberant 'ctags' program not found" 1>&2; exit 1; }
		PROG="etags"
		TAGS_OPT="-a -o"
	fi
fi

# List of kinds supported by Exuberant Ctags 5.8
# generated by ctags --list-kinds
# --c-kinds was called --c-types before 2003
#    c  classes
#    d  macro definitions
#    e  enumerators (values inside an enumeration)
#    f  function definitions
#    g  enumeration names
#    l  local variables [off]
#    m  class, struct, and union members
#    n  namespaces
#    p  function prototypes [off]
#    s  structure names
#    t  typedefs
#    u  union names
#    v  variable definitions
#    x  external and forward variable declarations [off]

if [ "$IS_EXUBERANT" ]
then	FLAGS="--c-kinds=+dfmstuv"
elif [ ! "$EMACS_MODE" ]
then	FLAGS="-dt"
fi

# Use -I option to ignore a macro
if [ "$IS_EXUBERANT" ]
then	IGNORE_IDENTIFIES="-I pg_node_attr+"
fi

trap "ret=$?; rm -rf /tmp/$$; exit $ret" 0 1 2 3 15
rm -f ./$TAGS_FILE

# this is outputting the tags into the file 'tags', and appending
find `pwd`/ \( -name tmp_install -prune -o -name tmp_check -prune \) \
	-o \( -name "*.[chly]" -o -iname "*makefile*" -o -name "*.mk" -o -name "*.in" \
	-o -name "*.sql" -o -name "*.p[lm]" \) -type f -print |
	xargs $PROG $TAGS_OPT $TAGS_FILE $FLAGS $IGNORE_IDENTIFIES

# Sorting non-Exuberant ctags file allows for fast searching of the tags file.
# Since etags file has a header that we cannot sort in with the other entries
# we skip the sort step.
if [ ! "$IS_EXUBERANT" -a ! "$EMACS_MODE" ]
then	LC_ALL=C
	export LC_ALL
	sort $TAGS_FILE >/tmp/$$ && mv /tmp/$$ $TAGS_FILE
fi

# create symbolic links
if [ ! "$NO_SYMLINK" ]
then    find . \( -name 'CVS' -prune \) -o \( -name .git -prune \) -o -type d -print |
	while read DIR
	do	[ "$DIR" != "." ] && ln -f -s `echo "$DIR" | sed 's;/[^/]*;/..;g'`/$TAGS_FILE "$DIR"/$TAGS_FILE
	done
fi
